import axios from 'axios'
import { Message } from 'view-ui-plus'
import { useUserStore } from '@/stores/user'
import router from '@/router'
import { config } from '@/config'

class HttpRequest {
    constructor(baseURL) {
        this.baseURL = baseURL
        this.queue = {} // 请求队列
    }

    // 获取axios配置
    getConfig() {
        return {
            baseURL: this.baseURL,
            timeout: 10000,
            headers: {
                'Content-Type': 'application/json;charset=utf-8'
            }
        }
    }

    // 拦截器
    interceptors(instance) {
        // 请求拦截器
        instance.interceptors.request.use(
            (config) => {
                // 添加全局的loading...
                if (!Object.keys(this.queue).length) {
                    // 开始loading
                }
                this.queue[config.url] = true

                const userStore = useUserStore()
                if (userStore.token) {
                    config.headers['Authorization'] = `Bearer ${userStore.token}`
                }
                return config
            },
            (error) => {
                return Promise.reject(error)
            }
        )

        // 响应拦截器
        instance.interceptors.response.use(
            (response) => {
                delete this.queue[response.config.url]
                if (!Object.keys(this.queue).length) {
                    // 结束loading
                }

                const { code, data, message } = response.data
                if (code === 200) {
                    return data
                } else {
                    Message.error(message || '系统错误')
                    // 特殊状态码处理
                    switch (code) {
                        case 401:
                            const userStore = useUserStore()
                            userStore.logout()
                            router.push('/login')
                            break
                        case 403:
                            router.push('/403')
                            break
                        case 500:
                            router.push('/500')
                            break
                    }
                    return Promise.reject(new Error(message || '系统错误'))
                }
            },
            (error) => {
                delete this.queue[error.config.url]
                if (!Object.keys(this.queue).length) {
                    // 结束loading
                }
                
                let message = ''
                if (error.response) {
                    switch (error.response.status) {
                        case 404:
                            message = '请求地址不存在'
                            break
                        case 408:
                            message = '请求超时'
                            break
                        default:
                            message = '系统异常'
                    }
                } else {
                    message = '网络异常，请检查网络连接'
                }
                Message.error(message)
                return Promise.reject(error)
            }
        )
    }

    // 创建实例
    request(options) {
        const instance = axios.create()
        const newOptions = { ...this.getConfig(), ...options }
        this.interceptors(instance)
        return instance(newOptions)
    }

    // 封装请求方法
    get(url, params, options = {}) {
        return this.request({
            method: 'get',
            url,
            params,
            ...options
        })
    }

    post(url, data, options = {}) {
        return this.request({
            method: 'post',
            url,
            data,
            ...options
        })
    }

    put(url, data, options = {}) {
        return this.request({
            method: 'put',
            url,
            data,
            ...options
        })
    }

    delete(url, params, options = {}) {
        return this.request({
            method: 'delete',
            url,
            params,
            ...options
        })
    }
}

export const request = new HttpRequest(config.baseURL)
export default request 